<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
<!--
1. 函数的prototype属性:
	* 每个函数都有一个prototype属性,他默认指向一个Object空对象(即称为:原型对象);
	* 原型对象中有一个属性constructor,他指向函数对象;
2. 给原型对象添加属性(一般都是方法，类似Java的静态属性和方法属于类本身的):
	* 作用:函数的所有的实例对象自动拥有原型中的属性(方法);
-->
<script>
function Fun(){
	
}
console.log(Fun.prototype) // 默认是Object空对象
//原型对象中有一个属性constructor,他指向函数对象
console.log(Fun.prototype.constructor === Fun)	
	
</script>

<!-- 2. "显示原型"和"隐式原型"
2.1 每个函数function都有一个prototype属性，即"显示原型"(属性);
2.2 每个实例对象都有一个__proto__,可称之为"隐式原型"(属性);
2.3 对象的隐式原型的值为其构造函数的显示原型的值;
2.4
2.5 总结:
	* 函数的prototype属性:在定义函数时候自动添加,默认值是一个空Object对象(即:{});
	* 对象的__proto__属性:创建对象时自动添加的,默认值为构造函数的prototype属性值;
	* 程序员能够操作"显示原型",但不能直接操作"隐式原型"(ES6之前);
	
-->
<script>
//定义函数的是偶自动添加 this.prototype = {}
function Fn(){
	
}
//创建对象实例的时候自顶添加 fn.__proto__ = Fn.prototype
var fn = new Fn()


console.log("fn.__proto__:"+fn.__proto__)
console.log("Fn.prototype:"+Fn.prototype)
console.log(fn.__proto__ === Fn.prototype)//true


Fn.prototype.test = function(){
	console.log("test()")
}

fn.test()//test()

/*
[1]. fn称为"实例对象",只拥有 __proto__ 属性;
[2]. function Fun()称为"函数对象",拥有__proto__属性和 prototype属性(一个空的Object的实例对象);
[3]. Fun.prototype 称为Fun"原型对象",实际上就是[2]所表述的prototype属性(一个空的Object的实例对象);
*/

/*
1. 函数的"显示原型"指向的是一个默认的空Object对象(但Object不满足)
*/
console.log(Fn.prototype instanceof Object) //true
console.log(Object.prototype instanceof Object) //false
console.log(Function.prototype instanceof Object)//true

/*
2. 所有的函数都是Function的实例(包含Function本身) 
*/
console.log(Function.__proto__ === Function.prototype)


/*
3. Object的原型对象是原型链的尽头
*/
console.log(Object.prototype.__proto__) // null

</script>
<!--
1.例如:
//Foo是一个当做函数来看的时候是一个"函数对象"是Function对象的实例
function Foo(){
	
}
相当于
var Foo = new Function()

2. 注意:
Function = new Function()
即Funcation函数对象是自己本身new出来的一个实例
function Function()的实例的__proto__指向自己本身的Function.prototype而Function.prototype又指向function Function()

3. 所有的 function Xxx().__proto__ 都指向 Funcation.prototype,因为他们都是函数对象Function的实例

Foo.protortype --- {}
Foo.__proto__ --- {}
-->
<script>
function Foo(){
	
}
var foo = new Foo()
console.log("*************************")
console.log(foo.__proto__)//Object的函数对象
console.log(Foo.prototype)//Object的函数对象
console.log(Foo.__proto__)//Function.prototype
console.log(foo.__proto__ === Foo.prototype)// true

console.log(Foo.__proto__ === Function.prototype)//true
console.log(Object.prototype)//Object的原型对象
console.log(Object.__proto__ === Function.prototype)//true

var func = new Function()
console.log(func.__proto__)
console.log(Function.prototype)
console.log(func.__proto__ === Function.prototype)
</script>
<!--
+ 所有实例对象(Object 的实例对象 除外 )的__proto__属性指向Object的函数对象
+ 所有的函数对象的__proto__属性指向函数对象Function.prototype
+ 所有函数对象(Function除外)的prototype属性指向Object函数对象
+ Object函数对象的__proto__指向Object原型对象

-->

<script>
/*
	原型链继承 
*/

//父类
function Super(name,age){
	this.name = name
	this.age = age
}
//父类的原型对象的方法(类似于java的静态方法)
Super.prototype.showSpuer = function(){
	console.log("Super.showSpuer ... ")
}


//子类
function Sub(name,age,price){
	/*this.name = name
	this.age = age*/
	Super.call(this,name,age) // 为了得到属性(类似Java的反射将Super方法绑定到Sub上)
	this.price = price	
}

Sub.prototype = new Super() // 指定 Sub的原型对象为 Super的对象 
Sub.prototype.constructor = Sub // 修正构造函数为Sub本身的构造函数

// 子类的原型对象的方法
Sub.prototype.showSub = function(){
	console.log("Super.showSub ... ")
}

var sub = new Sub("Bob",15,130000)
console.log(sub)



</script>	
	
	</body>
</html>
